﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using AjaxControlToolkit;
using System.Web.UI;
using System.Diagnostics;
using System.ComponentModel;
using System.Web.UI.WebControls;
using System.Web.Script.Serialization;
using System.Collections;
[assembly: WebResource("Kevin.Controls.Grid.Grid.js", "text/javascript")]
[assembly: WebResource("Kevin.Controls.Grid.GridHelper.js", "text/javascript")]
[assembly: WebResource("Kevin.Controls.Grid.css", "text/css", PerformSubstitution = true)]
namespace Kevin.Controls
{
    /*-----------------------------------------------------------------------------------------------------------------------------------------------
     *  创建人：席吉波
     *  备注：
     *  Grid控件，该控件在刚开始的时候只是想单纯在客户端利用WebMethod获取数据展示数据使用，并可以给父页面的Html元素赋值；
     *   后来逐渐加入的功能有：
     *   1、导航：跳转至使用者给定Url地址，可接受参数
     *   2、弹出新页面： 在当前页面弹出使用者给定的Url，可接受参数
     *   3、子绑定：可以在当前数据行下面显示一个新的子Grid，并可传给该子Grid参数数据
     *   
     *  该控件还在持续更新中
     *-----------------------------------------------------------------------------------------------------------------------------------------------
     */
    /// <summary>
    /// 客户端列表控件
    /// </summary>
    //[RequiredScript(typeof(AsyncScripts))]
    [ClientScriptResource("Kevin.Controls.Grid", "Kevin.Controls.Grid.Grid.js")]
    [ClientScriptResource("Kevin.Controls.Grid", "Kevin.Controls.Grid.GridHelper.js")]
    [RequiredScript(typeof(CommonScripts))]    
    [ClientCssResource("Kevin.Controls.Grid.css")]
    [ParseChildren(true, "DataFields")]
    public class Grid : ScriptControlBase
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public Grid()
            : base(true, HtmlTextWriterTag.Div)
        { }

        protected override void OnPreRender(EventArgs e)
        {
            if (!DesignMode)
            {
                Page.ClientScript.GetCallbackEventReference(this, "", "", "");
            }
            base.OnPreRender(e);
        }

        protected override void Render(HtmlTextWriter writer)
        {
            if (DesignMode)
            {
                string strDesign = @"<div><table><thead><tr><th colspan='2'>查询条件</th><tr><th>控件ID</th><th>数据项</th></tr> </tr></thead>
                                            <tbody>
                                            {0}
                                            <tbody>  <tfoot></tfoot>      
                                    </table>{1}</div>";

                string strQueryParameter = "<tr><td>{0}</td><td>{1}</td></tr> ";
                string str0 = "";
                foreach (QueryParameter para in this.Parameters)
                {
                    str0 += string.Format(strQueryParameter, para.ControlID, para.DataPropertyName);
                }

                string strHead = "";
                string strBody = "";
                foreach (DataField field in this.DataFields)
                {
                    strHead += string.Format("<th>{0}</th>", field.HeaderText);
                    if (field is DataBoundField)
                    {
                        DataBoundField dbField = field as DataBoundField;
                        strBody += string.Format("<td>{0}</td>", dbField.FieldName);
                    }
                    if (field is LinkField)
                    {
                        LinkField dbField = field as LinkField;
                        strBody += string.Format("<td>{0}</td>", dbField.ItemText);
                    }
                    if (field is CommandFiled)
                    {
                        CommandFiled dbField = field as CommandFiled;
                        strBody += string.Format("<td>{0}</td>", dbField.ItemText);
                    }
                }

                string grid = string.Format("<table class='NormalGrid'><thead><tr>{0}</tr></thead><tbody><tr>{1}</tr></tbody><tfoot</tfoot>></table>"
                    , strHead, strBody);
                writer.Write(string.Format(strDesign, str0, grid));
            }
            else
            {
                base.Render(writer);
            }
        }

        protected override string SaveClientState()
        {
            if (!string.IsNullOrEmpty(QueryControlID) || this.Parameters.Count > 0)
            {
                return this.GetClientSate(this.Parameters, this.DataFields);

            }
            return base.SaveClientState();
        }

        protected override void LoadClientState(string clientState)
        {
            //base.LoadClientState(clientState);
        }

        /// <summary>
        /// 根据用户的选择将配置信息序列化成Json对象，以便保存至客户端
        /// </summary>
        /// <param name="parameters"></param>
        /// <param name="dataFields"></param>
        /// <returns></returns>
        private string GetClientSate(QueryParameterCollection parameters,DataFieldCollection dataFields)
        {
            string result = "";
            IList<GridQueryParameter> clientParameters = new List<GridQueryParameter>();
            foreach (QueryParameter item in parameters)
            {
                GridQueryParameter bindItem;
                //将服务器控件转换为客户端控件  
                Control ctr = this.FindControl(item.ControlID);
                if (ctr != null)
                {
                    string clientMethod = string.IsNullOrEmpty(item.GetValueClientMethod) ? this.GetClientControlDataMethod(ctr) : item.GetValueClientMethod;
                    bindItem = new GridQueryParameter(ctr.ClientID, item.DataPropertyName, clientMethod);
                }
                else
                {
                    bindItem = new GridQueryParameter("", item.DataPropertyName, "");
                }

                clientParameters.Add(bindItem);
            }

            IList<GridQueryParameter> commandParameter = new List<GridQueryParameter>();
            DataFieldCollection DataFieldList = new DataFieldCollection();
            foreach(DataField item in dataFields)
            {
                if (item is Kevin.Controls.CommandFiled)
                {
                    
                    CommandFiled command = item as Kevin.Controls.CommandFiled;
                    foreach (EditItem editItem in command.EditItems)
                    {
                         Control ctr=null;
                        GridQueryParameter bindItem =null;
                         if (command.TagPage == TagPage.Current)
                         {
                             ctr = this.FindControl(editItem.ControlID);
                             bindItem = new GridQueryParameter(editItem.ControlID, editItem.DataBoundFieldName, this.SetClientControlDataMethod(ctr, false));
                         }
                         if (command.TagPage == TagPage.Parent)
                         {
                             //对父页面控件进行赋值，请自己指定赋值方法
                             bindItem = new GridQueryParameter(editItem.ControlID, editItem.DataBoundFieldName, editItem.ParentPageControlSetValueMethod);
                         }
                        
                        commandParameter.Add(bindItem);
                    }
                    DataFieldList.Add(item);
                }
                else if (item is Kevin.Controls.ExtendFiled)
                {
                    ExtendFiled filed = item as ExtendFiled;
                    filed.GridID = this.FindControl(filed.GridID).ClientID;
                    if (string.IsNullOrEmpty(filed.ServicePath))
                    {
                        filed.ServicePath = this.ServicePath;
                    }
                    DataFieldList.Add(filed);
                }
                else
                {
                    DataFieldList.Add(item);
                }
            }

            GridClientState states = new GridClientState();
            states.DataFieldList = DataFieldList;
            states.GridQueryParameterList = clientParameters;
            states.EditCommandFieldStates = commandParameter;
            result = new JavaScriptSerializer().Serialize(states);

            return result;
        }

        /// <summary>
        /// 给当前页面赋值
        /// </summary>
        /// <param name="ctr"></param>
        /// <param name="isParent"></param>
        /// <returns></returns>
        private string SetClientControlDataMethod(Control ctr,bool isParent)
        {
            string clientMethod = "";
            
            if (ctr is TextBox)
                clientMethod = " _setNormalValue('" + ctr.ClientID + "','{0}'," + isParent.ToString().ToLower() + ") ";
            if (ctr is Label)
                clientMethod = " _setSpanValue('" + ctr.ClientID + "','{0}'," + isParent.ToString().ToLower() + ")";
            if (ctr is DropDownList)
                clientMethod = " _setDropDownListValue('" + ctr.ClientID + "','{0}'," + isParent.ToString().ToLower() + ")";
            if (ctr is CodeNameSelect)//从列表中选择进行赋值时请显示全称 Name(Code)这种格式
                clientMethod = "_setCodeNameSelectText('" + ctr.ClientID + "','{0}'," + isParent.ToString().ToLower() + ")";
            if (ctr is CheckBox)
                clientMethod = " _setChecked('" + ctr.ClientID + "','{0}'," + isParent.ToString().ToLower() + ") ";
            return clientMethod;
        }
        /// <summary>
        /// 根据控件类型确定其客户端的取值方法名
        /// </summary>
        /// <param name="ctr"></param>
        /// <returns></returns>
        private string GetClientControlDataMethod(Control ctr)
        {
            
            string clientMethod = "";
            return clientMethod;
            if (ctr is TextBox)
                clientMethod = " _getNormalValue('" + ctr.ClientID + "'); ";
            if (ctr is Label)
                clientMethod = " _getSpanValue('" + ctr.ClientID + "');";
            if (ctr is DropDownList)
                clientMethod = " _getDropDownListValue('" + ctr.ClientID + "'); ";
            if (ctr is CodeNameSelect)
                clientMethod = @"_getCodeNameSelectValue('" + ctr.ClientID + "');";
            if (ctr is CheckBox)
                clientMethod = " _getChecked('" + ctr.ClientID + "'); ";
            return clientMethod;
        }

        #region Properties

        /// <summary>
        /// 获取数据时的Service路径
        /// </summary>
        [UrlProperty]
        [ExtenderControlProperty]
        [TypeConverter(typeof(ServicePathConverter))]
        [ClientPropertyName("servicePath")]
        [Description("webService路径")]
        public virtual string ServicePath
        {
            get { return GetPropertyValue("servicePath", String.Empty); }
            set { SetPropertyValue("servicePath", value); }
        }

        /// <summary>
        /// The Insert web service method to be called.
        /// </summary>
        [DefaultValue("")]
        [RequiredProperty]
        [ExtenderControlProperty]
        [ClientPropertyName("queryMethod")]
        public virtual string QueryMethod
        {
            get { return GetPropertyValue("queryMethod", String.Empty); }
            set { SetPropertyValue("queryMethod", value); }
        }
        /// <summary>
        /// Grid的样式名称
        /// </summary>
        [ExtenderControlProperty]
        [ClientPropertyName("gridCssClass")]
        public string GridCssClass
        {
            get { return GetPropertyValue("gridCssClass", String.Empty); }
            set { SetPropertyValue("gridCssClass", value); }
        }

        /// <summary>
        /// 单页显示的数据行数
        /// </summary>
        [ExtenderControlProperty]
        [ClientPropertyName("pageSize")]
        public int PageSize
        {
            get { return GetPropertyValue("pageSize", Int32.MaxValue); }
            set { SetPropertyValue("pageSize", value); }
        }


        /// <summary>
        /// The Query Control ID.
        /// </summary>
        [DefaultValue("")]
        [RequiredProperty]
        [ExtenderControlProperty]
        [ClientPropertyName("QueryControlID")]
        public virtual string QueryControlID
        {
            get { return GetPropertyValue("QueryControlID", String.Empty); }
            set 
            {
                Control ctr = this.FindControl(value);
                //if (ctr != null)
                //{
                //    SetPropertyValue("QueryControlID", ctr.ClientID);
                //}
                //else
                //{
                    SetPropertyValue("QueryControlID", value);
                //}
            }
        }


        /// <summary>
        /// Auto Get Data.
        /// </summary>
        [DefaultValue("")]
        [RequiredProperty]
        [ExtenderControlProperty]
        [ClientPropertyName("AutoGetData")]
        public virtual bool AutoGetData
        {
            get { return GetPropertyValue("AutoGetData", false); }
            set
            {
                //Control ctr = this.FindControl(value);
                SetPropertyValue("AutoGetData", value);               
            }
        }

        private QueryParameterCollection _parameters=new QueryParameterCollection();
        /// <summary>
        /// 查询参数集合
        /// </summary>
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public QueryParameterCollection Parameters
        {
            get { return _parameters; }
        }

        private DataFieldCollection _dataFields=new DataFieldCollection();
        /// <summary>
        /// 绑定数据集合
        /// </summary>
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        [PersistenceMode(PersistenceMode.InnerProperty)]
        public DataFieldCollection DataFields
        {
            get { return _dataFields; }
            set { _dataFields = value; }
        }

        /// <summary>
        /// 分页导航的位置，默认在Grid的下方
        /// </summary>
        [DefaultValue("")]
        [RequiredProperty]
        [ExtenderControlProperty]
        [ClientPropertyName("PagerPlace")]
        public PagerPlace PagerPlace
        {
            get { return GetPropertyValue("PagerPlace", PagerPlace.Bottom); }
            set { SetPropertyValue("PagerPlace", value); }
        }
        /// <summary>
        /// 是否允许开启动画效果
        /// </summary>
        [ExtenderControlProperty]
        [ClientPropertyName("AllowAnima")]
        public bool AllowAnima
        {
            get { return GetPropertyValue("AllowAnima", false); }
            set { SetPropertyValue("AllowAnima", value); }
        }
        
        //选择功能
        
        /// <summary>
        /// 是否启用选择功能选择，默认不启用
        /// </summary>
        [DefaultValue(false)]
        [RequiredProperty]
        [ExtenderControlProperty]
        [ClientPropertyName("EnableSelected")]
        public bool EnableSelected
        {
            get { return GetPropertyValue("EnableSelected", false); }
            set { SetPropertyValue("EnableSelected", value); }
        }

        /// <summary>
        /// 展开 收起功能 默认不开启
        /// </summary>
        [DefaultValue(false)]
        [RequiredProperty]
        [ExtenderControlProperty]
        [ClientPropertyName("ExtendGrid")]
        internal bool ExtendGrid
        {
            get { return GetPropertyValue("ExtendGrid", false); }
            set { SetPropertyValue("ExtendGrid", value); }
        }

        /// <summary>
        /// 用于展开时，主Grid 给 子Grid 传递查询参数的值，以“,”分割
        /// </summary>
        [ExtenderControlProperty]
        [ClientPropertyName("QueryParameterValues")]
        public string QueryParameterValues
        {
            get { return GetPropertyValue("QueryParameterValues", ""); }
            set { SetPropertyValue("QueryParameterValues", value); }
        }

        #endregion

        #region Helper

        [DebuggerStepThrough]
        internal V GetPropertyValue<V>(string propertyName, V nullValue)
        {
            if (ViewState[propertyName] == null)
            {
                return nullValue;
            }
            return (V)ViewState[propertyName];
        }

        [DebuggerStepThrough]
        internal void SetPropertyValue<V>(string propertyName, V value)
        {
            ViewState[propertyName] = value;
        }

        private Control FindControlByPath(Control rootControl, string idPath)
        {
            int depth = 0;
            string[] idPaths = idPath.Split('.');
            while (idPaths.Length > depth)
            {
                rootControl = rootControl.FindControl(idPaths[depth]);
                depth++;
            }
            return rootControl;
        }

        #endregion
    }
}
